package org.iabako.client.ui.form.business.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.HTMLPanel;
import org.iabako.client.navigation.NavigationController;
import org.iabako.client.tools.IabakoAsyncCallback;
import org.iabako.client.ui.form.AbstractForm;
import org.iabako.client.ui.layout.field.*;
import org.iabako.client.ui.layout.widget.dialogbox.IabakoDialogBox;
import org.iabako.client.user.AuthenticateUserProvider;
import org.iabako.shared.entity.business.Address;
import org.iabako.shared.entity.business.Client;
import org.iabako.shared.entity.enumeration.Company;
import org.iabako.shared.entity.enumeration.Country;
import org.iabako.shared.entity.enumeration.Gender;
import org.iabako.shared.iservice.business.ClientServiceAsync;
import org.iabako.shared.tools.GenericTools;

import java.util.Arrays;
import java.util.List;


/**
 * TODO javadoc
 * Date: 24/11/13
 * Time: 18:22
 */
public class ClientInformationForm extends AbstractForm {

    interface MyUiBinder extends UiBinder<HTMLPanel, ClientInformationForm> {
    }

    protected MyUiBinder binderClientForm = GWT.create(MyUiBinder.class);
    protected final ClientServiceAsync clientServiceAsync = ClientServiceAsync.Util.getInstance();

    @UiField
    InputText number;
    @UiField
    InputText firstName;
    @UiField
    InputText lastName;
    @UiField
    RadioButtonList gender;
    @UiField
    InputManualDate birthday;
    @UiField
    InputText email;
    @UiField
    InputText addressLine1;
    @UiField
    InputText addressLine2;
    @UiField
    InputText city;
    @UiField
    InputText zipCode;
    @UiField
    SelectList country;
    @UiField
    InputText phoneNumber1;
    @UiField
    InputText phoneNumber2;
    @UiField
    ClientCustomFieldsForm clientCustomFieldsForm;
    @UiField
    RadioButtonList company;
    @UiField
    InputText companyName;
    @UiField
    LabelText addContactAction;
    @UiField
    HTMLPanel companyContactPanel;
    @UiField
    InputText contactName;
    @UiField
    InputTextEmail contactEmail;
    @UiField
    InputText contactPhoneNumber1;
    @UiField
    InputText contactPhoneNumber2;
    @UiField
    InputText contactPosition;
    @UiField
    InputSwitch clientEnabled;

    public ClientInformationForm() {
        initWidget(binderClientForm.createAndBindUi(this));

        setDefaultValues();

        setHandlers();
    }

    private void setHandlers() {
        gender.getRadioButtons().get(Gender.man).addHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                company.setValue(null);
                enableCompanyFields(false);
            }
        }, ClickEvent.getType());
        gender.getRadioButtons().get(Gender.woman).addHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                company.setValue(null);
                enableCompanyFields(false);
            }
        }, ClickEvent.getType());

        company.getRadioButtons().get(Company.company).addHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                gender.setValue(null);
                enableCompanyFields(true);
            }
        }, ClickEvent.getType());

        addContactAction.getLabel().addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent clickEvent) {
                addContactAction.setVisible(false);
                companyContactPanel.setVisible(true);
            }
        });

        clientEnabled.addValueChangeHandler(new ValueChangeHandler() {
            public void onValueChange(ValueChangeEvent valueChangeEvent) {
                if (!clientEnabled.getValue() && entity != null && entity.getId() != null) {
                    clientServiceAsync.hasInstallments((Client) entity, new IabakoAsyncCallback<Boolean>() {
                        public void onSuccess(Boolean result) {
                            super.onSuccess(result);
                            if (result) {
                                handleClientDisabledNotPossible();
                            }
                        }
                    });
                }
            }
        });
    }

    public void handleClientDisabledNotPossible() {
        IabakoDialogBox iabakoDialogBox = new IabakoDialogBox("client_disabled_not_possible_title", "client_disabled_not_possible_text");
        iabakoDialogBox.setCloseOnlySimplePopup(true);
        NavigationController.getInstance().show(iabakoDialogBox);
        clientEnabled.setValue(true);
    }

    public void enableCompanyFields(boolean isCompany) {
        companyName.setVisible(isCompany);
        firstName.setVisible(!isCompany);
        lastName.setVisible(!isCompany);
        birthday.setVisible(!isCompany);
        addContactAction.setVisible(isCompany && !hasContact());
        companyContactPanel.setVisible(isCompany && hasContact());
    }

    private boolean hasContact() {
        return !GenericTools.isEmpty(contactPosition.getValue()) || !GenericTools.isEmpty(contactName.getValue())
                || !GenericTools.isEmpty(contactEmail.getValue()) || !GenericTools.isEmpty(contactPhoneNumber1.getValue())
                || !GenericTools.isEmpty(contactPhoneNumber2.getValue());
    }

    private void setDefaultValues() {
        clientEnabled.setValue(true);
        //By default, set clients country with enterprise country
        country.setRawEnumValue(AuthenticateUserProvider.getUser().getEnterprise().getAddress().getCountry());
    }

    protected Client getEntity() {
        if (entity == null) {
            entity = new Client();
        }

        boolean isCompany = company.getValue() != null;

        Client client = (Client) entity;
        client.setDisabled(!clientEnabled.getValue());
        client.setNumber(number.getValue());
        client.setGender(isCompany ? Gender.company : (Gender) gender.getValue());
        client.setFirstName(!isCompany ? firstName.getValue() : null);
        client.setLastName(!isCompany ? lastName.getValue() : null);
        if (isCompany) {
            client.setName(companyName.getValue());
        }
        client.setEmail(email.getValue());
        client.setBirthdayString(!isCompany ? GenericTools.formatDateToString(birthday.getValue()) : null);

        Address address = new Address();
        address.setAddressLine1(addressLine1.getValue());
        address.setAddressLine2(addressLine2.getValue());
        address.setCity(city.getValue());
        address.setCountry((Country) country.getEnumValue());
        address.setZipCode(zipCode.getValue());
        client.setAddress(address);

        client.setPhoneNumber1(phoneNumber1.getValue());
        client.setPhoneNumber2(phoneNumber2.getValue());

        //Company contact fields
        client.setContactPosition(isCompany ? contactPosition.getValue() : null);
        client.setContactName(isCompany ? contactName.getValue() : null);
        client.setContactEmail(isCompany ? contactEmail.getValue() : null);
        client.setContactPhoneNumber1(isCompany ? contactPhoneNumber1.getValue() : null);
        client.setContactPhoneNumber2(isCompany ? contactPhoneNumber2.getValue() : null);

        clientCustomFieldsForm.setCustomFieldsValueToClient(client);

        return client;
    }

    protected void setClient(Client client) {

        this.entity = client;

        boolean isCompany = client.getGender() == Gender.company;

        clientEnabled.setValue(!client.isDisabled());
        number.setValue(client.getNumber());
        gender.setValue(isCompany ? null : client.getGender());
        company.setValue(isCompany ? Company.company : null);
        firstName.setValue(client.getFirstName());
        lastName.setValue(client.getLastName());
        companyName.setValue(isCompany ? client.getName() : null);
        email.setValue(client.getEmail());
        birthday.setValue(GenericTools.getDateFromString(client.getBirthdayString()));

        if (client.getAddress() != null) {
            addressLine1.setValue(client.getAddress().getAddressLine1());
            addressLine2.setValue(client.getAddress().getAddressLine2());
            city.setValue(client.getAddress().getCity());
            country.setEnumValue(client.getAddress().getCountry());
            zipCode.setValue(client.getAddress().getZipCode());
        } else {
            country.setRawEnumValue(null);
        }

        phoneNumber1.setValue(client.getPhoneNumber1());
        phoneNumber2.setValue(client.getPhoneNumber2());

        //Company contact fields
        contactPosition.setValue(client.getContactPosition());
        contactName.setValue(client.getContactName());
        contactEmail.setValue(client.getContactEmail());
        contactPhoneNumber1.setValue(client.getContactPhoneNumber1());
        contactPhoneNumber2.setValue(client.getContactPhoneNumber2());

        enableCompanyFields(isCompany);

        initializeCustomFieldsForm();
    }

    public void initializeCustomFieldsForm() {
        clientCustomFieldsForm.setParentForm(parentForm);
        clientCustomFieldsForm.initialize((Client) entity);
    }

    protected List<IField> getMandatoryFields() {
        boolean isCompany = company.getValue() != null;
        return isCompany ? Arrays.asList((IField) number, companyName) : Arrays.asList((IField) number, gender, firstName, lastName);
    }

    public boolean validate() {
        return false;
    }
}
